package com.example.myapplication.ui.gallery;

import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;

import com.example.myapplication.MainActivity;
import com.example.myapplication.MyApplication;
import com.example.myapplication.databinding.FragmentGalleryBinding;
import com.example.myapplication.peripheral.CSVDataLogger;
import com.example.myapplication.peripheral.DataUtils;
import com.example.myapplication.peripheral.PlotWave;
import com.example.myapplication.peripheral.TimeUtils;
import com.example.myapplication.peripheral.UserBluetooth;
import com.github.mikephil.charting.data.Entry;
import com.st.st25sdk.STException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class GalleryFragment extends Fragment implements NFCInterface{
    private FragmentGalleryBinding binding;
    public List<Entry> hrEntries = new ArrayList<>();
    public int hrEntries_index = 0;
    public List<Entry> rriEntries = new ArrayList<>();
    public int rriEntries_index = 0;
    public List<Entry> respEntries = new ArrayList<>();
    public int respEntries_index = 0;
    public List<Entry> spo2Entries = new ArrayList<>();
    public int spo2Entries_index = 0;

    private boolean isSortedByAddress = true; // 默认按时间排序
    private byte[] nfc_data_buf;


    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        GalleryViewModel galleryViewModel = new ViewModelProvider(this).get(GalleryViewModel.class);

        binding = FragmentGalleryBinding.inflate(inflater, container, false);
        View root = binding.getRoot();
        NFCInterfaceInstant.getInstance().init(this);
        // 初始化图表
        PlotWave.getInstance().initChart(binding.chartHR,"HR", Color.RED, 0,220);
        PlotWave.getInstance().initChart(binding.chartRRI, "RRI", Color.parseColor("#FF7F0E"),60,300);
        PlotWave.getInstance().initChart(binding.chartRESP,"RESP", Color.parseColor("#36D1DC"), 6,30);
        PlotWave.getInstance().initChart(binding.chartSPO2, "SPO2", Color.parseColor("#E100FF"), 90,100);

        binding.recordButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getNFC_DATA();
            }
        });
        binding.emptyButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message message = new Message();
                message.what = HANDLE_MESSAGE_NFC_DATA;
                message.obj = "";
                handler.sendMessage(message);
            }
        });
        binding.sortButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                toggleSortOrder();
            }
        });
        binding.exportButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                CSVDataLogger csvDataLogger = new CSVDataLogger("nfc", 1,"Timestamp, hr, spo2, resp\n");
                if (nfc_data_buf != null) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                // 创建一个列表来存储所有数据块，以便排序
                                List<DataBlock> dataBlocks = new ArrayList<>();
                                // 将数据解析为DataBlock对象
                                for (int i = 0; i < nfc_data_buf.length; i += 8) {
                                    byte[] timestampBytes = Arrays.copyOfRange(nfc_data_buf, i, i + 4);
                                    long timestamp = DataUtils.bytesToUnsignedInt(timestampBytes);
                                    byte[] dataBytes = Arrays.copyOfRange(nfc_data_buf, i + 4, i + 8);
                                    int address = MainActivity.SMARTAG_BEGIN_ADDR_COMPACT_DATA + i;
                                    dataBlocks.add(new DataBlock(address, timestampBytes, dataBytes, timestamp));
                                }
                                // 按时间戳排序
                                Collections.sort(dataBlocks, (a, b) -> Long.compare(a.timestamp, b.timestamp));
                                // 构建输出字符串
                                for (DataBlock block : dataBlocks) {
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                        String[] strings = new String[]{
                                                TimeUtils.convertSecondsToDateTime(block.timestamp,1),
                                                String.valueOf(block.dataBytes[0] & 0xFF), // hr
                                                String.valueOf(block.dataBytes[1] & 0xFF), // spo2
                                                String.valueOf(block.dataBytes[2] & 0xFF)  // resp
                                        };
                                        csvDataLogger.addData(strings);
                                        Log.d("lzy", "Exporting data: " + Arrays.toString(strings));
                                        Toast.makeText(MyApplication.getContext(), "export path：" + csvDataLogger.getCSVFilePath(), Toast.LENGTH_SHORT).show();
                                    }
                                }
                            } catch (Exception e) {
                            }
                        }
                    }).start();
                }
            }
        });
        return root;
    }

    private void toggleSortOrder() {
        isSortedByAddress = !isSortedByAddress;
        if (isSortedByAddress) {
            binding.sortButton.setText("按地址排序");
            // 执行按时间排序的逻辑
            if (nfc_data_buf != null) {
                setSortedByAddress(nfc_data_buf);
            } else {
                Toast.makeText(MyApplication.getContext(), "No NFC Data", Toast.LENGTH_LONG).show();
            }
        } else {
            binding.sortButton.setText("按时间排序");
            if(nfc_data_buf != null) {
                setSortedByTime(nfc_data_buf);
            } else
            {
                Toast.makeText(MyApplication.getContext(), "No NFC Data", Toast.LENGTH_LONG).show();
            }
        }
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

    @Override
    public void getNFC_DATA() {
        _getNFC_DATA();
    }

    public void _getNFC_DATA(){
        if(MainActivity.getTag() == null) {
            Toast.makeText(MyApplication.getContext(), "No NFC Device", Toast.LENGTH_LONG).show();
        }
        else {
            Toast.makeText(MyApplication.getContext(), "Reading NFC Data", Toast.LENGTH_LONG).show();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        byte[] byt = MainActivity.getTag().readBytes(MainActivity.SMARTAG_BEGIN_ADDR_COMPACT_DATA, MainActivity.SMARTAG_END_ADDR_COMPACT_DATA);
                        nfc_data_buf = Arrays.copyOf(byt, byt.length); // 完整复制
                        if (byt != null) {
                            Log.d("lzy", "length: " + byt.length);
                            setSortedByAddress(byt);

                            MainActivity.getTag().writeBytes(116, new byte[]{(byte) 0xaa,0x00,0x00,0x00});
                        }
                    } catch (STException e) {
                        //throw new RuntimeException(e);
                    }
                }
            }).start();
        }
    }

    /**
     * 按地址排序
     */
    public void setSortedByAddress(byte[] byt){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    StringBuilder stringBuilder = new StringBuilder();
                    for (int i = 0; i < byt.length; i += 8) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            // 第一行：地址 + 4字节十六进制 + 时间
                            stringBuilder.append(String.format("地址%-5d: %02X %02X %02X %02X    %s\r\n",
                                    MainActivity.SMARTAG_BEGIN_ADDR_COMPACT_DATA + i,
                                    byt[i], byt[i + 1], byt[i + 2], byt[i + 3],
                                    TimeUtils.convertSecondsToDateTime(DataUtils.bytesToUnsignedInt(Arrays.copyOfRange(byt, i, i + 4)))));
                            // 第二行：地址 + 4字节十六进制 + 生理数据
                            stringBuilder.append(String.format("地址%-5d: %02X %02X %02X %02X    hr:%3d spo2:%3d resp:%3d\r\n\r\n",
                                    MainActivity.SMARTAG_BEGIN_ADDR_COMPACT_DATA + i + 4,
                                    byt[i + 4], byt[i + 5], byt[i + 6], byt[i + 7],
                                    byt[i + 4] & 0xFF, byt[i + 5] & 0xFF, byt[i + 6] & 0xFF));
                        }
                    }
                    // 写textview
                    Message msg = new Message();
                    msg.what = HANDLE_MESSAGE_NFC_DATA;
                    msg.obj = stringBuilder.toString();
                    handler.sendMessage(msg);

                    // 绘图
                    Message msg2 = new Message();
                    msg2.what = HANDLE_MESSAGE_NFC_DATA2;
                    msg2.obj = byt;
                    handler.sendMessage(msg2);
                } catch (Exception e) {}
            }
        }).start();
    }

    public void setSortedByTime(byte[] byt) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    StringBuilder stringBuilder = new StringBuilder();

                    // 创建一个列表来存储所有数据块，以便排序
                    List<DataBlock> dataBlocks = new ArrayList<>();

                    // 将数据解析为DataBlock对象
                    for (int i = 0; i < byt.length; i += 8) {
                        byte[] timestampBytes = Arrays.copyOfRange(byt, i, i + 4);
                        long timestamp = DataUtils.bytesToUnsignedInt(timestampBytes);
                        byte[] dataBytes = Arrays.copyOfRange(byt, i + 4, i + 8);
                        int address = MainActivity.SMARTAG_BEGIN_ADDR_COMPACT_DATA + i;
                        dataBlocks.add(new DataBlock(address, timestampBytes, dataBytes, timestamp));
                    }
                    // 按时间戳排序
                    Collections.sort(dataBlocks, (a, b) -> Long.compare(a.timestamp, b.timestamp));
                    // 构建输出字符串
                    for (DataBlock block : dataBlocks) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            // 第一行：地址 + 4字节十六进制 + 时间
                            stringBuilder.append(String.format("地址%-5d: %02X %02X %02X %02X    %s\r\n",
                                    block.address,
                                    block.timestampBytes[0], block.timestampBytes[1],
                                    block.timestampBytes[2], block.timestampBytes[3],
                                    TimeUtils.convertSecondsToDateTime(block.timestamp)));

                            // 第二行：地址 + 4字节十六进制 + 生理数据
                            stringBuilder.append(String.format("地址%-5d: %02X %02X %02X %02X    hr:%3d spo2:%3d resp:%3d\r\n\r\n",
                                    block.address + 4,
                                    block.dataBytes[0], block.dataBytes[1],
                                    block.dataBytes[2], block.dataBytes[3],
                                    block.dataBytes[0] & 0xFF, block.dataBytes[1] & 0xFF, block.dataBytes[2] & 0xFF));
                        }
                    }
                    // 写textview
                    Message msg = new Message();
                    msg.what = HANDLE_MESSAGE_NFC_DATA;
                    msg.obj = stringBuilder.toString();
                    handler.sendMessage(msg);

                    // 绘图
                    Message msg2 = new Message();
                    msg2.what = HANDLE_MESSAGE_NFC_DATA1;
                    msg2.obj = byt;
                    handler.sendMessage(msg2);
                } catch (Exception e) {
                }
            }
        }).start();
    }
    // 辅助类，用于存储和排序数据块
    private static class DataBlock {
        int address;
        byte[] timestampBytes;
        byte[] dataBytes;
        long timestamp;

        DataBlock(int address, byte[] timestampBytes, byte[] dataBytes, long timestamp) {
            this.address = address;
            this.timestampBytes = timestampBytes;
            this.dataBytes = dataBytes;
            this.timestamp = timestamp;
        }
    }


    private static final int HANDLE_MESSAGE_NFC_DATA = 1;
    private static final int HANDLE_MESSAGE_NFC_DATA1 = 2;
    private static final int HANDLE_MESSAGE_NFC_DATA2 = 3;
    Handler handler = new Handler(new Handler.Callback(){
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case HANDLE_MESSAGE_NFC_DATA: {
                    String str = (String) msg.obj;
                    binding.textView.setText(str);
                }break;
                case HANDLE_MESSAGE_NFC_DATA1:{
                    plotChart((byte[]) msg.obj);
                }break;
                case HANDLE_MESSAGE_NFC_DATA2:{
                    plotChartByAddress((byte[]) msg.obj);
                }break;
            }
            return true;
        }
    });

    // 数据点辅助类
    class DataPoint {
        long timestamp;
        int hr;
        int so2;
        int resp;
        public DataPoint(long timestamp, int hr, int so2, int resp) {
            this.timestamp = timestamp;
            this.hr = hr;
            this.so2 = so2;
            this.resp = resp;
        }
    }

    private void plotChart(byte[] byt) {
        // 创建一个列表来保存所有数据点
        List<DataPoint> dataPoints = new ArrayList<>();
        // 首先解析所有数据
        for(int i = 0; i < byt.length; i += 8) {
            long timestamp = DataUtils.bytesToUnsignedInt(Arrays.copyOfRange(byt, i, i+4));
            int hr = byt[i+4];
            int so2 = byt[i+5];
            int resp = byt[i+6];
            // 创建数据点对象并添加到列表
            dataPoints.add(new DataPoint(timestamp, hr, so2, resp));
        }
        // 按时间戳排序
        Collections.sort(dataPoints, (a, b) -> Long.compare(a.timestamp, b.timestamp));

        // 打印排序后的数据点（调试用）
        Log.d("DataDebug","=== Sorted DataPoints (by timestamp) ===");
        for (DataPoint dp : dataPoints) {
            Log.d("DataDebug",
                    String.format("Timestamp: %d | HR: %d | SPO2: %d | RESP: %d",
                            dp.timestamp, dp.hr, dp.so2, dp.resp)
            );
        }
        Log.d("DataDebug","=======================================");

        // 清空现有数据
        hrEntries.clear();
        rriEntries.clear();
        spo2Entries.clear();
        respEntries.clear();
        hrEntries_index = 0;
        rriEntries_index = 0;
        spo2Entries_index = 0;
        respEntries_index = 0;
        // 按排序后的顺序添加数据
        for (DataPoint dp : dataPoints) {
            // 添加HR数据
            hrEntries.add(new Entry(hrEntries_index++, dp.hr));
            // 添加RRI数据
            if (dp.hr == 0) {
                rriEntries.add(new Entry(rriEntries_index++, 0));
            } else {
                rriEntries.add(new Entry(rriEntries_index++, (60.0f * 256) / dp.hr));
            }
            // 添加SPO2数据
            spo2Entries.add(new Entry(spo2Entries_index++, dp.so2));
            // 添加RESP数据
            respEntries.add(new Entry(respEntries_index++, dp.resp));
        }
        // 更新所有图表
        PlotWave.getInstance().updateChart(binding.chartHR, hrEntries, "HR", Color.RED, 1009, 1009);
        PlotWave.getInstance().updateChart(binding.chartRRI, rriEntries, "RRI", Color.parseColor("#FF7F0E"), 1009, 1009);
        PlotWave.getInstance().updateChart(binding.chartSPO2, spo2Entries, "SPO2", Color.parseColor("#E100FF"), 1009, 1009);
        PlotWave.getInstance().updateChart(binding.chartRESP, respEntries, "RESP", Color.parseColor("#36D1DC"), 1009, 1009);
    }
    private void plotChartByAddress(byte[] byt) {
        // 创建一个列表来保存所有数据点
        List<DataPoint> dataPoints = new ArrayList<>();
        // 首先解析所有数据
        for(int i = 0; i < byt.length; i += 8) {
            long timestamp = DataUtils.bytesToUnsignedInt(Arrays.copyOfRange(byt, i, i+4));
            int hr = byt[i+4];
            int so2 = byt[i+5];
            int resp = byt[i+6];
            // 创建数据点对象并添加到列表
            dataPoints.add(new DataPoint(timestamp, hr, so2, resp));
        }
        // 按时间戳排序
        //Collections.sort(dataPoints, (a, b) -> Long.compare(a.timestamp, b.timestamp));

        // 打印排序后的数据点（调试用）
        Log.d("DataDebug","=== Sorted DataPoints (by timestamp) ===");
        for (DataPoint dp : dataPoints) {
            Log.d("DataDebug",
                    String.format("Timestamp: %d | HR: %d | SPO2: %d | RESP: %d",
                            dp.timestamp, dp.hr, dp.so2, dp.resp)
            );
        }
        Log.d("DataDebug","=======================================");

        // 清空现有数据
        hrEntries.clear();
        rriEntries.clear();
        spo2Entries.clear();
        respEntries.clear();
        hrEntries_index = 0;
        rriEntries_index = 0;
        spo2Entries_index = 0;
        respEntries_index = 0;
        // 按排序后的顺序添加数据
        for (DataPoint dp : dataPoints) {
            // 添加HR数据
            hrEntries.add(new Entry(hrEntries_index++, dp.hr));
            // 添加RRI数据
            if (dp.hr == 0) {
                rriEntries.add(new Entry(rriEntries_index++, 0));
            } else {
                rriEntries.add(new Entry(rriEntries_index++, (60.0f * 256) / dp.hr));
            }
            // 添加SPO2数据
            spo2Entries.add(new Entry(spo2Entries_index++, dp.so2));
            // 添加RESP数据
            respEntries.add(new Entry(respEntries_index++, dp.resp));
        }
        // 更新所有图表
        PlotWave.getInstance().updateChart(binding.chartHR, hrEntries, "HR", Color.RED, 1009, 1009);
        PlotWave.getInstance().updateChart(binding.chartRRI, rriEntries, "RRI", Color.parseColor("#FF7F0E"), 1009, 1009);
        PlotWave.getInstance().updateChart(binding.chartSPO2, spo2Entries, "SPO2", Color.parseColor("#E100FF"), 1009, 1009);
        PlotWave.getInstance().updateChart(binding.chartRESP, respEntries, "RESP", Color.parseColor("#36D1DC"), 1009, 1009);
    }
}
